# SparkParasitic.cmake
# 
# 此模块用于寄生构建项目，即那些依赖于宿主项目的多个组件的项目。
# 本模块提供了一系列宏（函数）来简化寄生项目的构建和打包过程。
# 
# 使用方法：
# 1. 包含此模块
# 2. 使用 spark_enable_packages() 启用 CPack 组件打包功能
# 3. 使用 spark_begin_package 和 spark_end_package 定义包组件
# 4. 在定义的包组件范围内，使用 spark_add_parasitic 添加寄生文件
# 
# 注意： 确保在使用此模块之前已包含 CPack 模块。

# 以下是 cpakc 组件定义语法，在用于寄生构建时将其拆分模式作为寄生项目打包的部分
    # 添加一个组件的语法结构，但作用于 Spark 构建时则会进行拆分操作
    # cpack_add_component(compname
    #                     [DISPLAY_NAME name]
    #                     [DESCRIPTION description]
    #                     [HIDDEN | REQUIRED | DISABLED ]
    #                     [GROUP group]
    #                     [DEPENDS comp1 comp2 ... ]
    #                     [INSTALL_TYPES type1 type2 ... ]
    #                     [DOWNLOADED]
    #                     [ARCHIVE_FILE filename]
    #                     [PLIST filename])

    # 当 CPack 文档中出现 (component based installers only) 时，变量将交由 cpack_add_component 来设置

# 启用 CPack DEB 组件打包功能
macro(spark_enable_packages)
    # 设置必要的 CPack 变量以启用组件安装和自定义 DEB 文件名
    set(CPACK_DEB_COMPONENT_INSTALL ON)
    # 设置 CPACK_DEBIAN_FILE_NAME 为 DEB_DEFAULT 以启用 CPACK_DEBIAN_<COMPONENT>_FILE_NAME 自定义输出文件名
    set(CPACK_DEBIAN_FILE_NAME      "DEB-DEFAULT")
    # 设置所有组件包都统一使用使用短描述(预留，使用注意)
    # set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
        # "SparkParasitic - CPack Component Installation Example")
    # include(CPack)
endmacro(spark_enable_packages)

# 定义一个 autogen 包组件
macro(spark_autogen_package)
    spark_begin_package(autogen)
        spark_install_file(/tmp/ ${CMAKE_CURRENT_LIST_FILE})
        add_package_descript(cmake/spark-deb-package.descript)
    spark_end_package()
endmacro(spark_autogen_package)


# 开始定义一个新的包组件
# _component 参数指定组件名称
# _component_description 提供组件描述，这将用于 deb 文件的详细信息字段
macro(spark_begin_package _component)
    # 记录当前正在配置的组件
    set(SPARK_COMPONENT ${_component})
    # 缓存记录描述信息
    set(_SPARK_COMPONENT_DESCRIPTION "${ARGN}")
    if(NOT "${_SPARK_COMPONENT_DESCRIPTION}" STREQUAL "")
        # 打印信息，帮助调试和确认配置正确
        message("[SparkParastic] 正在配置组件: ${ARGN}")
    endif(NOT "${_SPARK_COMPONENT_DESCRIPTION}" STREQUAL "")
    # 清理残留的缓存描述信息
    unset(_SPARK_COMPONENT_DESCRIPTION)
endmacro(spark_begin_package)

# 结束当前组件的定义
# 这将添加一个具有合适配置的 CPack 组件
macro(spark_end_package)
    # 经过组件化的测试：
        # 1. 包的描述信息应放置在组件上，而不是 CPACK_DEBIAN_<COMPONENT>_DESCRIPTION 上
        #    具体的：参考变量处的 (component based installers only) 关键信息
    if (NOT "${SPARK_COMPONENT}" STREQUAL "")
        cpack_add_component(${SPARK_COMPONENT} 
            DESCRIPTION "${SPARK_COMPONENT_DESCRIPTION}")
        # 清除已处理的组件名和描述
        unset(SPARK_COMPONENT)
        unset(SPARK_COMPONENT_DESCRIPTION)
    endif()
endmacro(spark_end_package)


# 添加寄生文件到当前的组件中
# _buildoption 激活构建选项，如果设置为 OFF 则不构建此文件
# _buildmessage 是在构建时显示的消息
# _buildfile 是待构建的文件路径
macro(spark_add_parasitic_build _buildfile _buildoption _buildmessage)
    set(_parasitic_file ${_buildfile})

    # 如果源文件不存在，检查是否存在于设定的路径中
    if(EXISTS ${_parasitic_file})
        # 无需其他操作，文件存在
    elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_parasitic_file})
        set(_parasitic_file ${CMAKE_CURRENT_SOURCE_DIR}/${_buildfile})
    endif()

    # 如果找到文件，根据构建选项决定是否添加到组件中
    if(EXISTS ${_parasitic_file})
        option(${_buildoption} ${_buildmessage} OFF)
        # 根据 option 的实际值决定是否添加文件到组件
        include(${_parasitic_file})
        if (${_buildoption})
            return()
        endif()
    endif()
endmacro(spark_add_parasitic_build _buildfile _buildoption _buildmessage)

# 当使用此模块时，开发者可以使用以上定义的宏来构建复杂的多组件项目

# 只是在使用此模块时，即会认为您需要进行多重打包
# 另外像 SPARK_COMPONENT_DESCRIPTION 的组件描述已交由 SparkDebPackageConfig.cmake 设置
